home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / rend10.lzh / REND1.0 / GraphicSubSystem / display.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-08  |  9.3 KB  |  377 lines

  1. /*
  2.  * Title:
  3.  *    display.c
  4.  *
  5.  * Authors:
  6.  *    Michael P. Schenck
  7.  *
  8.  * Purpose:
  9.  *    Contains all the routines needed for opening and closing the 
  10.  *    renderers output screen.  This is a custom screen which can
  11.  *    be opened in a variety of resolutions.  The routines will 
  12.  *    support more than one bitplane of data, but for the wireframe
  13.  *    graphics, no more is needed.
  14.  *    A screen clearing function is provided which clears the bitmap
  15.  *      of the display that is currently hidden.  Output always goes
  16.  *    to the hidden screen.  A line drawing function will draw a
  17.  *    line on the hidden bitplane. 
  18.  *    A getinput function gets a character from the keyboard.  You
  19.  *    can tell the function either to wait or to just see if there
  20.  *    is a character available and continue.
  21.  *    The last function provided is a pause function that waits
  22.  *     the duration specified (secs, microsecs). 
  23.  * 
  24.  * Copyright Info:
  25.  *    Copyright (C) 1993, 1994 -- by Michael P. Schenck, 
  26.  *    (mps4466@ultb.isc.rit.edu)
  27.  *    
  28.  *    This program is free software; you can redistribute it and/or modify
  29.  *    it under the terms of the GNU General Public License as published
  30.  *    by the Free Software Foundation; either version 2 of the License,
  31.  *    or (at your option) any later version.
  32.  *
  33.  *    This software is distributed in the hope that it will be useful, but
  34.  *    WITHOUT ANY WARRANTY; without even the implied warranty of
  35.  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  36.  *    GNU General Public License for more details.
  37.  *
  38.  *      For a copy of the GNU General Public License
  39.  *    write to the Free Software Foundation, 675 Mass Ave,
  40.  *    Cambridge, MA  02139, USA.
  41.  *
  42.  */
  43.  
  44. #include <proto/diskfont.h>
  45. #include <proto/exec.h>
  46. #include <proto/graphics.h>
  47. #include <proto/intuition.h>
  48. #include <exec/memory.h> 
  49. #include <stdlib.h>
  50. #include <math.h>
  51. #include "/include/errors.h"
  52. #include "/include/display.h"
  53.  
  54.   /* System startup structures. */
  55.  
  56. static struct NewScreen newscreen = {
  57.    0,0,320,200,
  58.    3,0,0,NULL,CUSTOMSCREEN|CUSTOMBITMAP|SCREENQUIET,
  59.    NULL,NULL,
  60.    NULL,NULL
  61. };
  62.    
  63. static struct NewWindow newwindow = {
  64.    0,0,320,200,0,0,VANILLAKEY,
  65.    SIMPLE_REFRESH | ACTIVATE | NOCAREREFRESH | BORDERLESS | RMBTRAP,
  66.    NULL,NULL,NULL,NULL,NULL,
  67.    320,200,320,200,CUSTOMSCREEN
  68. };
  69.  
  70.  /* Blank pointer data. */
  71.  
  72. static USHORT chip pointer[22] = {
  73.    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  74.    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
  75.    0x0000,0x0000,0x0000,0x0000
  76. };                           
  77.    
  78. static long   __OSlibversion = 33;   
  79. static struct Window *window = NULL;
  80. static struct timerequest timermsg;
  81. static struct MsgPort *treplyport = NULL;
  82. static UBYTE timeropen,depth;
  83. static UWORD *colortable,width,height,code;
  84. static ULONG signalmask,signals,class;
  85.  
  86. struct Screen *screen = NULL;
  87. struct BitMap *dbbitmaps[2];
  88.  
  89. static UWORD bytewidth,blitsize;
  90. static UBYTE buffered;
  91.  
  92.     /* Assembly blitter functions (rasterasm.a). */
  93.  
  94. void __asm blitclearmem(register __d0 UWORD blitsize,
  95.             register __a0 APTR clear);
  96.  
  97. void __asm blitline(register __d0 WORD x0,
  98.             register __d1 WORD y0,
  99.             register __d2 WORD x1,
  100.             register __d3 WORD y1,
  101.             register __d4 UWORD bytewidth,
  102.             register __a0 APTR firstpixel);
  103.  
  104. struct BitMap *allocatebitmap(void);
  105. void  releasebitmap(struct BitMap *);
  106. UBYTE getmessage(void);
  107. void cleanup(void);
  108.  
  109.  /* Opens and initializes the display module. */
  110.  
  111. UBYTE opendisplay(UWORD *coltable,UWORD swidth,UWORD sheight,UBYTE sdepth)
  112.  
  113. {  
  114.    width = swidth;
  115.    height = sheight;
  116.    depth = sdepth; 
  117.    if((dbbitmaps[0] = allocatebitmap()) == NULL)
  118.        return(MEM_ALLOC_FAILURE);
  119.    if((dbbitmaps[1] = allocatebitmap()) == NULL) {
  120.        releasebitmap(dbbitmaps[0]);
  121.     return(MEM_ALLOC_FAILURE);
  122.    } 
  123.    newscreen.Width = width;
  124.    newscreen.Height = height;
  125.    newscreen.Depth = depth;
  126.    if (width>320)
  127.       newscreen.ViewModes = HIRES;   
  128.    if (height>200)
  129.       newscreen.ViewModes = newscreen.ViewModes | LACE;
  130.    newscreen.CustomBitMap = dbbitmaps[0];
  131.    newwindow.Width = width;
  132.    newwindow.Height = height;
  133.    newwindow.MinWidth = width;
  134.    newwindow.MinHeight = height;
  135.    newwindow.MaxWidth = width;
  136.    newwindow.MaxHeight = height;
  137.    colortable = coltable;
  138.    if ((screen = OpenScreen(&newscreen)) == NULL) {
  139.       cleanup(); 
  140.       return(OPEN_VIEW_FAILURE);
  141.    }  
  142.    screen->RastPort.Flags = DBUFFER;      
  143.    newwindow.Screen = screen;
  144.    if ((window = OpenWindow(&newwindow)) == NULL) {
  145.       cleanup();
  146.       return(OPEN_VIEW_FAILURE);
  147.    }
  148.    LoadRGB4(&(screen->ViewPort),colortable,(UBYTE)pow2((double)depth)); 
  149.    SetPointer(window,pointer,9,16,0,0);   
  150.    timeropen = OpenDevice(TIMERNAME,UNIT_MICROHZ,(struct IORequest *) &timermsg,0);
  151.    if (timeropen) {
  152.       cleanup();
  153.       return(OPEN_VIEW_FAILURE);
  154.    }
  155.    if ((treplyport = (struct MsgPort *) CreatePort(0,0)) == NULL) {
  156.       cleanup();
  157.       return(OPEN_VIEW_FAILURE);
  158.    }
  159.    signalmask = 1L << window->UserPort->mp_SigBit;
  160.  
  161.    bytewidth = width >> 3;            /* Width of screen in bytes, for blitter. */
  162.    blitsize = (height << 6)+(width >> 4);    /* Blitsize for clearing the screen. */
  163.    buffered = 1;                /* Set screen buffer. */
  164.                
  165.    OwnBlitter();                   /* Do initial screen clearing. */
  166.    WaitBlit();       
  167.    blitclearmem(blitsize,(APTR)dbbitmaps[0]->Planes[0]);     
  168.    blitclearmem(blitsize,(APTR)dbbitmaps[1]->Planes[0]); 
  169.    DisownBlitter(); 
  170.  
  171.    return(0);
  172. }
  173.  
  174.  /* Closes down the display module. */
  175.  
  176. void closedisplay()
  177.  
  178. {
  179.    cleanup();
  180. }
  181.             
  182.  /* Clears the screen. NOTE: The screen is always cleared in displaygraphics(). */
  183.  
  184. void clearscreen()
  185.  
  186. {
  187.    OwnBlitter();
  188.    WaitBlit();
  189.    blitclearmem(blitsize,(APTR)dbbitmaps[buffered]->Planes[0]);
  190.    DisownBlitter();  
  191. }
  192.  
  193.  /* Draws a line using the blitter. */
  194.  
  195. void line(WORD x0, WORD y0, WORD x1, WORD y1)
  196.  
  197. {
  198.    UBYTE lineinside = TRUE;
  199.  
  200.    OwnBlitter();
  201.    WaitBlit();
  202.    
  203.        /* 2D clipping to the screen. */
  204.    
  205.    if(x0 < 0) {
  206.       if(x1 >= 0) {
  207.           y0 = y0+(y1-y0)*(0-x0)/(x1-x0);
  208.           x0 = 0;
  209.       }
  210.       else
  211.          lineinside = FALSE;
  212.     }
  213.     else if(x1 < 0) {
  214.        y1 = y0+(y1-y0)*(0-x0)/(x1-x0);
  215.        x1 = 0;
  216.     }
  217.     if(x0 >= width) {
  218.        if(x1 < width) {
  219.           y0 = y0+(y1-y0)*(width-x0)/(x1-x0);
  220.           x0 = width-1;
  221.        }
  222.        else
  223.           lineinside = FALSE;
  224.     }
  225.     else if(x1 >= width) {
  226.        y1 = y0+(y1-y0)*(width-x0)/(x1-x0);
  227.        x1 = width-1;
  228.     }
  229.     if(y0 < 0) {
  230.        if(y1 >= 0) {
  231.           x0 = x0+(x1-x0)*(0-y0)/(y1-y0);
  232.           y0 = 0;
  233.        }
  234.        else
  235.           lineinside = FALSE;
  236.     }
  237.     else if(y1 < 0) {
  238.        x1 = x0+(x1-x0)*(0-y0)/(y1-y0);
  239.        y1 = 0;
  240.     }
  241.     if(y0 >= height) {
  242.        if(y1 < height) {
  243.           x0 = x0+(x1-x0)*(height-y0)/(y1-y0);
  244.           y0 = height-1;
  245.        }
  246.        else
  247.           lineinside = FALSE;
  248.     }
  249.     else if(y1 >= height) {
  250.        x1 = x0+(x1-x0)*(height-y0)/(y1-y0);
  251.        y1 = height-1;
  252.     } 
  253.      
  254.      /* Blit the line if it is on the screen. */
  255.      
  256.     if(lineinside==TRUE)  
  257.        blitline(x0,y0,x1,y1,bytewidth,(APTR)dbbitmaps[buffered]->Planes[0]);
  258.     DisownBlitter();  
  259. }
  260.  
  261.  /* Switch bitmap displays. */
  262.  
  263. void showgraphics()
  264. {
  265.    screen->RastPort.BitMap = dbbitmaps[buffered];
  266.    screen->ViewPort.RasInfo->BitMap = dbbitmaps[buffered];
  267.    MakeScreen(screen); 
  268.    RethinkDisplay();
  269.  
  270.    if(buffered == 0)
  271.       buffered = 1;
  272.    else
  273.       buffered = 0; 
  274. }
  275.  
  276.  /* Allocate a bitmap. */
  277.  
  278. struct BitMap *allocatebitmap()
  279.  
  280. {
  281.     struct BitMap *bitmap;
  282.     UBYTE i;
  283.     
  284.     if ((bitmap = (struct BitMap *)AllocMem(sizeof(struct BitMap),MEMF_CLEAR))!=NULL) { 
  285.        InitBitMap(bitmap,depth,width,height);
  286.        for (i=0;i<depth;i++) {
  287.           if((bitmap->Planes[i] = (PLANEPTR)AllocRaster(width,height))==NULL)
  288.              return(NULL);
  289.        }
  290.     }
  291.     else
  292.        return(NULL);
  293.     return(bitmap);
  294. }
  295.  
  296.  /* Releases a bitmap. */
  297.  
  298. void releasebitmap(struct BitMap *bitmap)
  299.  
  300. {
  301.     UBYTE i;
  302.     
  303.        for (i=0;i<depth;i++) {
  304.              FreeRaster(bitmap->Planes[i],width,height);
  305.        FreeMem(bitmap,sizeof(struct BitMap));
  306.     }
  307. }
  308.  
  309.  /* Waits for input from intuition. */
  310.  
  311. UBYTE getinput(UBYTE style)
  312. {
  313.    if(getmessage())
  314.       return((UBYTE)code);
  315.    if(style == WAIT) {
  316.       while(TRUE) {
  317.      signals = Wait(signalmask);
  318.          if (signals & signalmask) {
  319.         if(getmessage())
  320.            return((UBYTE)code);
  321.      }
  322.       }
  323.    }
  324.    else
  325.       return(FALSE);
  326. }
  327.  
  328.  /* Get an intuition message.  If there is one, only looking for keyboard input. */
  329.  
  330. UBYTE getmessage()
  331. {
  332.    struct IntuiMessage *message;
  333.    
  334.    if((message = (struct IntuiMessage *)GetMsg(window->UserPort)) != NULL) {
  335.       class = message->Class;
  336.       code = message->Code;      
  337.       ReplyMsg((struct Message *)message);
  338.       if(class == VANILLAKEY)
  339.      return(TRUE);
  340.       else
  341.          return(FALSE);
  342.    }
  343.    return(FALSE);
  344. }
  345.  
  346.  /* Pauses system until time has elapsed. */
  347.  
  348. void pause(ULONG secs,ULONG microsecs)
  349.  
  350. {
  351.    timermsg.tr_node.io_Command = TR_ADDREQUEST;
  352.    timermsg.tr_node.io_Message.mn_ReplyPort = treplyport;
  353.    timermsg.tr_time.tv_secs = secs;
  354.    timermsg.tr_time.tv_micro = microsecs;
  355.    DoIO((struct IORequest *) &timermsg);
  356. }  
  357.    
  358.  /* Close everything that has been opened. */  
  359.         
  360. void cleanup(void) 
  361.  
  362. {   
  363.    if (treplyport)
  364.       DeletePort(treplyport);
  365.    if (!timeropen)
  366.       CloseDevice((struct IORequest *) &timermsg);
  367.    if (window)   
  368.       CloseWindow(window);
  369.    if (screen)
  370.       CloseScreen(screen);
  371.       
  372.    releasebitmap(dbbitmaps[0]);
  373.    releasebitmap(dbbitmaps[1]);
  374. }
  375.  
  376.  
  377.